<?php


namespace App\Task;

use Hyperf\Task\Annotation\Task;
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\Manager;
use MongoDB\Driver\Query;
use MongoDB\Driver\Command;
use MongoDB\Driver\WriteConcern;

class MongoTask
{
    /**
     * @var Manager
     */
    public $manager;

    /**
     * @Task
     * @param string $namespace
     * @param array $document
     * @return int|null
     */
    public function insert(string $namespace, array $document)
    {
        $writeConcern = new WriteConcern(WriteConcern::MAJORITY, 1000);
        $bulk = new BulkWrite();
        $bulk->insert($document);

        $result = $this->manager()->executeBulkWrite($namespace, $bulk, $writeConcern);
        return $result->getUpsertedCount();
    }

    /**
     * @Task
     * @param string $namespace
     * @param array $filter
     * @param array $options
     * @return array
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function query(string $namespace, array $filter = [], array $options = [])
    {
        $query = new Query($filter, $options);
        $cursor = $this->manager()->executeQuery($namespace, $query);
        return $cursor->toArray();
    }

    /**
     * @Task
     * @param string $db
     * @param array $filter
     * @return array
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function command(string $db, array $filter = [])
    {
        $command = new Command($filter);
        $result = $this->manager()->executeCommand($db,$command);
        return $result->toArray();
    }


    /**
     * @return Manager
     */
    public function manager()
    {
        if ($this->manager instanceof Manager) {
            return $this->manager;
        }
        $host = config('mongodb.default.host');
        $port = config('mongodb.default.port');
        $auth = [
            'username' => config('mongodb.default.username'),
            'password' => config('mongodb.default.password'),
            'authSource' => config('mongodb.default.db')
        ];
        $uri = 'mongodb://'.$host.':'.$port;
        return $this->manager = new Manager($uri, $auth);
    }

}